/**
 * Copyright (c) [2025] [AGIROS] 
 * [travoddsgen] is licensed under Mulan PSL v2. 
 * You can use this software according to the terms and conditions of the Mulan PSL v2. 
 * You may obtain a copy of Mulan PSL v2 at: 
 *          http://license.coscl.org.cn/MulanPSL2 
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 
 * See the Mulan PSL v2 for more details.
 */ 

#include "CppLangTypeNameVisitor.h"
#include "IDLParser.h"
#include <iostream>

void CppLangTypeNameVisitor::visit(ModuleDclNode& node) {
    moduleStack_.push_back(*node.identifier_);
    node.definitions_->accept(*this);
    moduleStack_.pop_back();
}

void CppLangTypeNameVisitor::visit(StructDefNode& node) {
    // 结构体名
    std::string structName = modulePrefix() + *node.identifier_;
    nameMap_[&node] = structName;
    // 父类
    if (node.parent_) {
        node.parent_->accept(*this);
    }
    // 递归访问子节点
    if (node.members_) {
        node.members_->accept(*this);
    }
}

void CppLangTypeNameVisitor::visit(StructForwardDclNode& node) {
    // 结构体名
    std::string structName = modulePrefix() + *node.identifier_;
    forwardDeclare_[structName] = "class";
}

void CppLangTypeNameVisitor::visit(UnionForwardDclNode& node) {
    // 联合名
    std::string unionName = modulePrefix() + *node.identifier_;
    forwardDeclare_[unionName] = "union";
}

void CppLangTypeNameVisitor::visit(UnionDefNode& node) {
    // 联合名
    std::string unionName = modulePrefix() + *node.identifier_;
    nameMap_[&node] = unionName;
    // switch
    node.switchType_->accept(*this);
    // 递归访问子节点
    if (node.cases_) {
        node.cases_->accept(*this);
    }
}

void CppLangTypeNameVisitor::visit(EnumDclNode& node) {
    // 标注中可能有bitbound值
    if (node.annotations_) {
        node.annotations_->accept(*this);
    }
    // 枚举名
    std::string enumName = modulePrefix() + *node.identifier_;
    nameMap_[&node] = enumName;
    // 成员中可能有ID值
    if (node.enumerators_) {
        node.enumerators_->accept(*this);
    }
}

void CppLangTypeNameVisitor::visit(ConstDclNode& node) {
    // 常量名
    std::string constName = modulePrefix() + *node.identifier_;
    nameMap_[&node] = constName;
    // 常量类型
    node.type_->accept(*this);
    // 常量表达式
    node.expression_->accept(*this);
}

void CppLangTypeNameVisitor::visit(BaseTypeNode& node) {
    std::string typeName;
    switch (node.type_) {
        case BaseTypeNode::Type::BOOLEAN:
            typeName = "char";
            break;
        case BaseTypeNode::Type::CHAR:
            typeName = "char";
            break;
        case BaseTypeNode::Type::WCHAR:
            typeName = "wchar_t";
            break;
        case BaseTypeNode::Type::UCHAR:
            typeName = "unsigned char";
            break;
        case BaseTypeNode::Type::SHORT:
            typeName = "short";
            break;
        case BaseTypeNode::Type::USHORT:
            typeName = "unsigned short";
            break;
        case BaseTypeNode::Type::LONG:
            typeName = "int";
            break;
        case BaseTypeNode::Type::ULONG:
            typeName = "unsigned int";
            break;
        case BaseTypeNode::Type::LONGLONG:
            typeName = "long long";
            break;
        case BaseTypeNode::Type::ULONGLONG:
            typeName = "unsigned long long";
            break;
        case BaseTypeNode::Type::FLOAT:
            typeName = "float";
            break;
        case BaseTypeNode::Type::DOUBLE:
            typeName = "double";
            break;
        case BaseTypeNode::Type::LONG_DOUBLE:
            typeName = "LongDouble";
            break;
        default:
            break;
    }
    nameMap_[&node] = typeName;
}

void CppLangTypeNameVisitor::visit(SequenceTypeNode& node) {
    if (node.size_) {
        node.size_->accept(*this);
    }
    // 递归访问子节点
    node.type_->accept(*this);
    std::string eleTypeName = findName(node.type_);
    nameMap_[&node] = "std::vector<" + eleTypeName + ">";
}

void CppLangTypeNameVisitor::visit(StringTypeNode& node) {
    if (node.size_) {
        node.size_->accept(*this);
    }
    nameMap_[&node] = "std::string";
}

void CppLangTypeNameVisitor::visit(WideStringTypeNode& node) {
    if (node.size_) {
        node.size_->accept(*this);
    }
    nameMap_[&node] = "std::wstring";
}

void CppLangTypeNameVisitor::visit(FixedPtTypeNode& node) {
    std::string typeName = "DDS_Fixed";
    nameMap_[&node] = typeName;
}

void CppLangTypeNameVisitor::visit(MapTypeNode& node) {
    if (node.size_) {
        node.size_->accept(*this);
    }
    // 依次访问子节点
    node.keyType_->accept(*this);
    node.valueType_->accept(*this);
    std::string keyTypeName = findName(node.keyType_);
    std::string valueTypeName = findName(node.valueType_);
    nameMap_[&node] = "std::map<" + keyTypeName + "," + valueTypeName + ">";
}

void CppLangTypeNameVisitor::visit(TypeDefDclNode& node) {
    // 被定义的类型名
    node.refType_->accept(*this);
    // 类型定义名
    std::string typeDefName = modulePrefix() + *node.identifier_;
    nameMap_[&node] = typeDefName;
    // 数组大小
    if (node.dims_) {
        node.dims_->accept(*this);
    }
}

std::string CppLangTypeNameVisitor::scopedName(ScopedNameNode* node, unsigned int length) {
    std::string scopedName = "";
    unsigned int nameLength = node->components_.size() > length ? length : node->components_.size();
    for (size_t i = 0; i < nameLength; ++i) {
        scopedName += *node->components_[i];
        if (i != nameLength - 1) {
            scopedName += "::";
        }
    }
    return scopedName;
}

void CppLangTypeNameVisitor::visit(ScopedNameNode& node) {
    // 以全局视角ScopedNameNode的名称
    std::string absScopedName = scopedName(&node, node.components_.size());
    // 从当前模块查找
    std::string scopedName = "";
    // ScopedNameNode中的模块名可能省略相同的前缀
    // 因此应该从模块栈中构造ScopedNameNode的完整名称
    scopedName = modulePrefix() + absScopedName;
    nameMap_[&node] = scopedName;
    // 遍历nameMap_查找与该node具备相同名称的类型定义的节点，建立映射
    bool found = false;
    for (auto& pair : nameMap_) {
        ASTNode& curNode = *pair.first;
        std::string& name = pair.second;
        DefinitionNode* typeNode = dynamic_cast<DefinitionNode*>(&curNode);
        if (typeNode) {
            if (name == scopedName) {
                found = true;
                scopedNameTypeMap_[&node] = typeNode;
                break;
            }
            if (name == absScopedName) {
                found = true;
                scopedNameTypeMap_[&node] = typeNode; 
                nameMap_[&node] = absScopedName;
                break;
            }
        }
    }
    //if (!found) {
    //    // 未找到对应的类型定义，报错
    //    std::cerr << "Error: Type definition not found for scoped name " << scopedName << std::endl;
    //    exit(1);
    //}
}

void CppLangTypeNameVisitor::visit(FixedArraySizeNode& node) {
    // 递归访问子节点
    node.size_->accept(*this);
    nameMap_[&node] = '[' + findName(node.size_) + ']';
}

void CppLangTypeNameVisitor::visit(OrExprNode& node) {
    // 递归访问子节点
    node.right_->accept(*this);
    std::string name = findName(node.right_);
    if (node.left_) {
        node.left_->accept(*this);
        name = findName(node.left_) + " | " + name;
    }
    nameMap_[&node] = name;
}

void CppLangTypeNameVisitor::visit(XorExprNode& node) {
    // 递归访问子节点
    node.right_->accept(*this);
    std::string name = findName(node.right_);
    if (node.left_) {
        node.left_->accept(*this);
        name = findName(node.left_) + " ^ " + name;
    }
    nameMap_[&node] = name;
}

void CppLangTypeNameVisitor::visit(AndExprNode& node) {
    // 递归访问子节点
    node.right_->accept(*this);
    std::string name = findName(node.right_);
    if (node.left_) {
        node.left_->accept(*this);
        name = findName(node.left_) + " & " + name;
    }
    nameMap_[&node] = name;
}

void CppLangTypeNameVisitor::visit(ShiftExprNode& node) {
    // 递归访问子节点
    node.right_->accept(*this);
    std::string name = findName(node.right_);
    if (node.left_) {
        node.left_->accept(*this);
        name = findName(node.left_) + " << " + name;
    }
    nameMap_[&node] = name;
}

void CppLangTypeNameVisitor::visit(AddExprNode& node) {
    // 递归访问子节点
    node.right_->accept(*this);
    std::string name = findName(node.right_);
    if (node.left_) {
        node.left_->accept(*this);
        if (node.op_ == AddExprNode::AddOp::PLUS) {
            name = findName(node.left_) + " + " + name;
        } else if (node.op_ == AddExprNode::AddOp::MINUS) {
            name = findName(node.left_) + " - " + name;
        }
    }
    nameMap_[&node] = name;
}

void CppLangTypeNameVisitor::visit(MultExprNode& node) {
    // 递归访问子节点
    node.right_->accept(*this);
    std::string name = findName(node.right_);
    if (node.left_) {
        node.left_->accept(*this);
        if (node.op_ == MultExprNode::MultOp::MULT) {
            name = findName(node.left_) + " * " + name;
        } else if (node.op_ == MultExprNode::MultOp::DIV) {
            name = findName(node.left_) + " / " + name;
        } else if (node.op_ == MultExprNode::MultOp::MOD) {
            name = findName(node.left_) + " % " + name;
        }
    }
    nameMap_[&node] = name;
}

void CppLangTypeNameVisitor::visit(UnaryExprNode& node) {
    node.expr_->accept(*this);
    std::string name = findName(node.expr_);
    if (node.op_ == UnaryExprNode::UnaryOp::PLUS) {
        name = "+" + name;
    } else if (node.op_ == UnaryExprNode::UnaryOp::MINUS) {
        name = "-" + name;
    } else if (node.op_ == UnaryExprNode::UnaryOp::NOT) {
        name = "!" + name;
    }
    nameMap_[&node] = name;
}

void CppLangTypeNameVisitor::visit(PrimaryExprNode& node) {
    if (node.scopedName_) {
        node.scopedName_->accept(*this);
        nameMap_[&node] = findName(node.scopedName_);
    } else if (node.literal_) {
        node.literal_->accept(*this);
        nameMap_[&node] = findName(node.literal_);
    } else if (node.constExpr_) {
        node.constExpr_->accept(*this);
        nameMap_[&node] = findName(node.constExpr_);
    }
}

void CppLangTypeNameVisitor::visit(LiteralNode& node) {
    if (node.type_ == LiteralNode::LiteralType::BOOLEAN)
        nameMap_[&node] = node.bvalue_ ? "true" : "false";
    else if (node.type_ == LiteralNode::LiteralType::INTEGER)
        nameMap_[&node] = std::to_string(node.ivalue_);
    else if (node.type_ == LiteralNode::LiteralType::FLOAT)
        nameMap_[&node] = std::to_string(node.fvalue_);
    else if (node.type_ == LiteralNode::LiteralType::STRING)
        nameMap_[&node] = node.svalue_;
}

std::string CppLangTypeNameVisitor::modulePrefix() {
    std::string prefix;
    for (auto& module : moduleStack_) {
        prefix += module + "::";
    }
    return prefix;
}

std::string CppLangTypeNameVisitor::findName(ASTNode* node) {
    if (nameMap_.find(node) == nameMap_.end()) {
        // 未找到对应的名称，报错
        std::cerr << "Error: Name not found for ASTNode" << std::endl;
        exit(1);
    }
    return nameMap_[node];
}

std::string CppLangTypeNameVisitor::findShortName(ASTNode* node) {
    std::string name = findName(node);
    // 如果是std::命名空间的类型，直接返回
    if (name.find("std::") == 0) {
        return name;
    }
    size_t pos = name.find_last_of(":");
    if (pos == std::string::npos) {
        return name;
    }
    return name.substr(pos + 1);
}

DefinitionNode* CppLangTypeNameVisitor::findType(ScopedNameNode* node) {
    if (scopedNameTypeMap_.find(node) == scopedNameTypeMap_.end()) {
        // 未找到对应的类型定义，报错
        std::cerr << "Error: Type definition not found for scoped name " << findName(node) << std::endl;
        exit(1);
    }
    return scopedNameTypeMap_[node];
}

std::string CppLangTypeNameVisitor::getBitbound(EnumDclNode& node) {
    // 查找枚举的bit_bound属性
    std::string bitBound = "32";
    if (node.annotations_ && node.annotations_->nodes_.size() > 0) {
        for (auto& attr : node.annotations_->nodes_) {
            TypeAnnotationNode* typeAnnotation = dynamic_cast<TypeAnnotationNode*>(attr);
            if (typeAnnotation->annotation_ == TypeAnnotationNode::AnnotationType::BIT_BOUND) {
                bitBound = findName(typeAnnotation->value_);
                break;
            }
        }
    }
    return bitBound;
}

void CppLangTypeNameVisitor::visit(IncludeDclNode& node) {
    // 递归访问子节点
    std::string includedFile = syntaxCheckerVisitor_.getIncludeFile(&node);
    // 生成被包含的文件
    SpecificationNode* includedSpec = parser_.parse(includedFile);
    // 建立node到file的映射
    syntaxCheckerVisitor_.visit(*includedSpec);
    // 将被包含的文件的类型添加到当前文件的类型中
    includedSpec->accept(*this);
}

std::string CppLangTypeNameVisitor::getIncludedFileName(IncludeDclNode& node) {
    // 递归访问子节点
    std::string includedFile = syntaxCheckerVisitor_.getIncludeFile(&node);
    std::string fileName = ParameterProcessor::getFileName(includedFile);
    return fileName;
}